<template>
    <div id="remote_terminal" class="terminal-container"></div>
</template>

<script setup>
import API from '@/js/api';
import { ref, onMounted, getCurrentInstance } from 'vue';

// 定义导出函数和事件
const { proxy } = getCurrentInstance();
const emit = defineEmits(['cmdstart']);
defineExpose({ setRemote, fit });

// 引入terminal相关的第三方库
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import '@xterm/xterm/css/xterm.css';

// remote相关的属性
const _remote = ref(null);

// terminal panel相关属性
const terminal = new Terminal({
    fontFamily: "'Ubuntu Mono', monospace",
    fontSize: 16,
    fontWeight: 'normal',
    scrollback: 2000
});

const fitAddon = new FitAddon();

async function setRemote(remote) {
    // console.log('RemoteMonitor remote = ', remote);
    if (remote == 'local') {
        return;
    }

    // 设置remote属性
    _remote.value = remote;

    // 接收远程ssh命令执行输出并展示
    await API.stopAsyncPolling();
    API.asyncTaskPolling(`${remote.id}:${remote.name}`, onRemoteCallback, 1000, 'local');

    // 清空已有的terminal数据
    clearTerminal();
}

async function onRemoteCallback(task_id, message) {
    // console.log(`onRemoteCallback task_id=${task_id}, message = `, message);
    if (message.event == 'stdio') {
        // addLog(message.data);
    } else if (message.event == 'stderr') {
        // addLog(message.data, 'red');
    } else if (message.event == 'cmdstart') {
        // console.log(message.data.command);
        const userHostPart = `\x1b[36m${_remote.value.username}@${_remote.value.host}${_remote.value.username == 'root' ? '#' : '$'}\x1b[0m`;
        // const commandPart = `\x1b[93m${message.data.command}\x1b[0m`; // 1;93 是加粗的亮黄色
        const commandPart = message.data.command;
        const formattedLog = `${userHostPart} ${commandPart}`;
        addLog(formattedLog);
        emit('cmdstart', message.data.command);
    } else if (message.event == 'cmdend') {
    } else if (message.event == 'connect_error') {
        console.warn('Peek connect_error message');
        let loading = ElLoading.service({
            lock: true,
            text: '网络连接失败',
            background: 'rgba(0, 0, 0, 0.7)'
        });
        setTimeout(() => {
            loading.close();
        }, 1000);
    } else {
        // console.log(`onRemoteCallback unknown event = ${message.event}`, message);
    }
}

//////////////////////////////////////////////////////////////////////
// terminal相关的属性和方法
function clearTerminal() {
    terminal.write('\x1b[3J\x1b[H\x1b[2J');
}

function addLog(logData, color = 'white') {
    if (logData.length == 0) {
        return;
    }

    // 定义颜色映射
    const colorCodes = {
        black: '30',
        red: '31',
        green: '32',
        yellow: '33',
        blue: '34',
        magenta: '35',
        cyan: '36',
        white: '37'
    };

    // 获取对应颜色的 ANSI 码，默认使用白色
    const colorCode = colorCodes[color] || '37';

    // 写入新的数据
    let logs = logData.split('\n');
    let output = '';
    logs.forEach((log) => {
        let logtxt = log.trim();
        if (logtxt.length !== 0) {
            // 使用 ANSI 转义码设置颜色
            const coloredLog = `\x1b[${colorCode}m${logtxt}\x1b[0m`;
            output += coloredLog + '\r\n';
        }
    });
    terminal.write(output);
}

function fit() {
    fitAddon.fit();
}

function initTerminal() {
    // 创建terminal实例并添加FitAddon
    terminal.loadAddon(fitAddon);
    terminal.open(document.getElementById('remote_terminal'));
    fitAddon.fit();
}

onMounted(() => {
    initTerminal();
});
</script>

<style scoped>
.terminal-container {
    background: #1e1e1e;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.terminal-container :deep(.xterm-viewport) {
    overflow: auto;
}

.terminal-container :deep(.xterm) {
    /* padding: 5px; */
    height: 100%;
}
</style>
